package app.itgungnir.compose.wan.business.settings

import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.itgungnir.compose.wan.theme.Palette
import app.itgungnir.compose.wan.theme.WanComposePreviewTheme
import app.itgungnir.compose.wan.theme.paletteColors
import app.itgungnir.compose.wan.widgets.WanDescription
import app.itgungnir.compose.wan.widgets.WanDivider
import app.itgungnir.compose.wan.widgets.WanTitle
import com.google.accompanist.flowlayout.FlowRow
import kotlin.math.roundToInt

@Composable
fun SettingsUI(
    showHotArticlesState: State<Boolean> = mutableStateOf(true),
    onShowHotArticlesToggled: (Boolean) -> Unit = {},
    nonPictureModeState: State<Boolean> = mutableStateOf(false),
    onNonPictureModeToggled: (Boolean) -> Unit = {},
    cacheSizeState: State<String> = mutableStateOf("0.0K"),
    onClearCacheSize: () -> Unit = {},
    darkModeExtendSystemState: State<Boolean> = mutableStateOf(true),
    onDarkModeExtendSystemToggled: (Boolean) -> Unit = {},
    darkModeEnabledState: State<Boolean> = mutableStateOf(false),
    onDarkModeEnabledToggled: (Boolean) -> Unit = {},
    colorPaletteIndexState: State<Int> = mutableStateOf(0),
    onColorPaletteIndexChanged: (Int) -> Unit = {},
    fontSizeIndexState: State<Int> = mutableStateOf(0),
    onFontSizeIndexChanged: (Int) -> Unit = {}
) {
    LazyColumn(
        modifier = Modifier
            .fillMaxWidth()
            .background(MaterialTheme.colors.surface)
            .padding(start = 15.dp, end = 15.dp)
    ) {
        item { WanTitle(modifier = Modifier.padding(top = 20.dp, bottom = 10.dp), content = "内容设置") }
        item {
            ContentSection(showHotArticlesState, onShowHotArticlesToggled, nonPictureModeState, onNonPictureModeToggled)
        }
        item { WanTitle(modifier = Modifier.padding(top = 20.dp, bottom = 10.dp), content = "缓存设置") }
        item { CacheSection(cacheSizeState, onClearCacheSize) }
        item { WanTitle(modifier = Modifier.padding(top = 20.dp, bottom = 10.dp), content = "深色模式") }
        item {
            DarkModeSection(
                darkModeExtendSystemState,
                onDarkModeExtendSystemToggled,
                darkModeEnabledState,
                onDarkModeEnabledToggled
            )
        }
        item { WanTitle(modifier = Modifier.padding(top = 20.dp, bottom = 10.dp), content = "主题颜色设置") }
        item { ColorPaletteSection(colorPaletteIndexState, onColorPaletteIndexChanged) }
        item { WanTitle(modifier = Modifier.padding(top = 20.dp, bottom = 10.dp), content = "字体大小设置") }
        item { FontSizeSection(fontSizeIndexState, onFontSizeIndexChanged) }
        item { Spacer(modifier = Modifier.height(50.dp)) }
    }
}

@Composable
private fun ContentSection(
    showHotArticlesState: State<Boolean> = mutableStateOf(true),
    onShowHotArticlesToggled: (Boolean) -> Unit = {},
    nonPictureModeState: State<Boolean> = mutableStateOf(false),
    onNonPictureModeToggled: (Boolean) -> Unit = {}
) {
    SectionBox {
        SwitchItem(icon = Icons.Outlined.ArrowCircleUp, title = "显示置顶文章", state = showHotArticlesState) {
            onShowHotArticlesToggled.invoke(it)
        }
        WanDivider(modifier = Modifier.padding(horizontal = 15.dp), fillWidth = true)
        SwitchItem(icon = Icons.Outlined.ImageNotSupported, title = "无图模式", state = nonPictureModeState) {
            onNonPictureModeToggled.invoke(it)
        }
    }
}

@Composable
private fun CacheSection(
    cacheSizeState: State<String> = mutableStateOf("0.0K"),
    onClearCacheSize: () -> Unit = {}
) {
    SectionBox {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clickable { onClearCacheSize.invoke() }
                .padding(horizontal = 15.dp, vertical = 10.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Icon(imageVector = Icons.Outlined.DeleteSweep, contentDescription = "", tint = MaterialTheme.colors.primary)
            Spacer(modifier = Modifier.width(10.dp))
            WanDescription(modifier = Modifier.weight(1F), content = "清除缓存")
            Spacer(modifier = Modifier.width(10.dp))
            WanDescription(content = cacheSizeState.value)
            Icon(
                imageVector = Icons.Outlined.ChevronRight,
                contentDescription = "",
                tint = MaterialTheme.colors.onBackground
            )
        }
    }
}

@Composable
private fun DarkModeSection(
    darkModeExtendSystemState: State<Boolean> = mutableStateOf(true),
    onDarkModeExtendSystemToggled: (Boolean) -> Unit = {},
    darkModeEnabledState: State<Boolean> = mutableStateOf(false),
    onDarkModeEnabledToggled: (Boolean) -> Unit = {}
) {
    SectionBox {
        SwitchItem(icon = Icons.Outlined.Android, title = "跟随系统", state = darkModeExtendSystemState) {
            onDarkModeExtendSystemToggled.invoke(it)
        }
        WanDivider(modifier = Modifier.padding(horizontal = 15.dp), fillWidth = true)
        SwitchItem(
            icon = Icons.Outlined.Build,
            title = "自定义设置",
            isEnabled = !darkModeExtendSystemState.value,
            state = darkModeEnabledState
        ) {
            onDarkModeEnabledToggled.invoke(it)
        }
    }
}

@Composable
private fun SwitchItem(
    modifier: Modifier = Modifier,
    icon: ImageVector,
    title: String,
    state: State<Boolean>,
    isEnabled: Boolean = true,
    onToggle: (Boolean) -> Unit
) {
    Row(
        modifier = modifier
            .fillMaxWidth()
            .padding(horizontal = 15.dp, vertical = 10.dp)
            .alpha(if (isEnabled) 1.0F else 0.4F),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(imageVector = icon, contentDescription = "", tint = MaterialTheme.colors.primary)
        Spacer(modifier = Modifier.width(10.dp))
        WanDescription(modifier = Modifier.weight(1F), content = title)
        Spacer(modifier = Modifier.width(10.dp))
        Switch(
            checked = state.value,
            onCheckedChange = {
                (state as? MutableState)?.value = it
                onToggle.invoke(it)
            },
            enabled = isEnabled
        )
    }
}

@Composable
private fun ColorPaletteSection(indexState: State<Int> = mutableStateOf(0), callback: (Int) -> Unit = {}) {
    SectionBox {
        FlowRow(modifier = Modifier.padding(start = 15.dp, end = 15.dp, top = 10.dp)) {
            paletteColors.forEachIndexed { index, palette ->
                ColorPaletteItem(palette = palette, index = index, indexState = indexState, callback = callback)
            }
        }
    }
}

@Composable
private fun ColorPaletteItem(
    palette: Palette,
    index: Int = 0,
    indexState: State<Int> = mutableStateOf(0),
    callback: (Int) -> Unit = {}
) {
    val selected = index == indexState.value
    Row(
        modifier = Modifier
            .size(60.dp)
            .padding(end = 10.dp, bottom = 10.dp)
            .clip(shape = CircleShape)
            .background(color = if (selected) MaterialTheme.colors.primary else MaterialTheme.colors.background)
            .padding(2.dp)
    ) {
        Column(
            modifier = Modifier
                .size(56.dp)
                .clip(shape = CircleShape)
                .background(color = MaterialTheme.colors.background)
                .padding(2.dp)
                .clip(shape = CircleShape)
                .clickable { callback.invoke(index) }
        ) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .weight(1F)
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxHeight()
                        .weight(1F)
                        .background(palette.lightPrimaryColor)
                )
                Spacer(modifier = Modifier.width(1.dp))
                Box(
                    modifier = Modifier
                        .fillMaxHeight()
                        .weight(1F)
                        .background(palette.darkPrimaryColor)
                )
            }
            Spacer(modifier = Modifier.height(1.dp))
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .weight(1F)
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxHeight()
                        .weight(1F)
                        .background(palette.lightSecondaryColor)
                )
                Spacer(modifier = Modifier.width(1.dp))
                Box(
                    modifier = Modifier
                        .fillMaxHeight()
                        .weight(1F)
                        .background(palette.darkSecondaryColor)
                )
            }
        }
    }
}

@Composable
private fun FontSizeSection(indexState: State<Int> = mutableStateOf(0), callback: (Int) -> Unit = {}) {
    SectionBox {
        Slider(
            modifier = Modifier.padding(horizontal = 25.dp),
            value = indexState.value * 0.25F,
            onValueChangeFinished = { callback.invoke(indexState.value) },
            onValueChange = { (indexState as? MutableState)?.value = (it * 4).roundToInt() },
            steps = 3
        )
        Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
            FontSizeTip(modifier = Modifier.weight(1F), text = "正常", fontSize = 14.sp)
            FontSizeTip(modifier = Modifier.weight(1F), text = "中等", fontSize = 16.sp)
            FontSizeTip(modifier = Modifier.weight(1F), text = "较大", fontSize = 18.sp)
            FontSizeTip(modifier = Modifier.weight(1F), text = "很大", fontSize = 20.sp)
            FontSizeTip(modifier = Modifier.weight(1F), text = "巨大", fontSize = 22.sp)
        }
        Spacer(modifier = Modifier.height(10.dp))
    }
}

@Composable
private fun FontSizeTip(modifier: Modifier = Modifier, text: String, fontSize: TextUnit) {
    Text(
        modifier = modifier,
        text = text,
        textAlign = TextAlign.Center,
        fontSize = fontSize,
        color = MaterialTheme.colors.onBackground
    )
}

@Composable
private fun SectionBox(modifier: Modifier = Modifier, component: @Composable ColumnScope.() -> Unit) {
    Column(
        modifier = modifier
            .fillMaxWidth()
            .clip(shape = RoundedCornerShape(size = 12.dp))
            .background(color = MaterialTheme.colors.background)
    ) {
        component.invoke(this)
    }
}

@Preview(name = "Settings light mode", showBackground = true)
@Preview(name = "Settings dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
@Composable
private fun SettingsPreview() {
    WanComposePreviewTheme {
        SettingsUI()
    }
}
